package com.learning.platform.service;

import com.learning.platform.dto.LessonRequest;
import com.learning.platform.dto.LessonResponse;
import com.learning.platform.entity.Course;
import com.learning.platform.entity.Lesson;
import com.learning.platform.enums.ErrorCode;
import com.learning.platform.exception.BusinessException;
import com.learning.platform.repository.CourseRepository;
import com.learning.platform.repository.LessonRepository;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 课程章节服务类
 * 处理课程章节的CRUD操作、获取章节列表及权限控制等业务逻辑
 */
@Service
@Transactional
public class LessonService {
    
    private final LessonRepository lessonRepository;
    private final CourseRepository courseRepository;
    private final EnrollmentService enrollmentService;
    
    /**
     * 构造函数，注入课程章节、课程和选课数据访问接口
     * @param lessonRepository 课程章节数据访问接口
     * @param courseRepository 课程数据访问接口
     * @param enrollmentService 选课服务接口（使用@Lazy解决循环依赖）
     */
    public LessonService(LessonRepository lessonRepository, CourseRepository courseRepository, @Lazy EnrollmentService enrollmentService) {
        this.lessonRepository = lessonRepository;
        this.courseRepository = courseRepository;
        this.enrollmentService = enrollmentService;
    }
    
    /**
     * 获取课程的所有章节列表
     * @param courseId 课程ID
     * @return 课程章节列表
     */
    @Transactional(readOnly = true)
    public List<LessonResponse> getCourseLessons(Long courseId) {
        return lessonRepository.findByCourseIdOrderByOrderNoAsc(courseId)
                .stream().map(lesson -> {
                    LessonResponse response = new LessonResponse(lesson);
                    return response;
                }).collect(Collectors.toList());
    }
    
    /**
     * 获取课程章节（带权限控制）
     * 根据用户是否已选课决定是否显示章节内容URL
     * @param courseId 课程ID
     * @param userId 用户ID
     * @return 课程章节列表（对于未选课用户，非免费章节的内容URL将被隐藏）
     */
    @Transactional(readOnly = true)
    public List<LessonResponse> getCourseLessonsWithPermission(Long courseId, Long userId) {
        // 检查用户是否已选课
        boolean isEnrolled = enrollmentService.isEnrolled(userId, courseId);
        
        return lessonRepository.findByCourseIdOrderByOrderNoAsc(courseId)
                .stream().map(lesson -> {
                    LessonResponse response = new LessonResponse(lesson);
                    // 如果用户未选课且该章节不免费，则隐藏内容URL
                    if (!isEnrolled && !lesson.getIsFree()) {
                        response = new LessonResponse(lesson) {
                            @Override
                            public String getContentUrl() { return null; }
                            @Override
                            public String getVideoUrl() { return null; }
                        };
                    }
                    return response;
                }).collect(Collectors.toList());
    }
    
    /**
     * 创建课程章节
     * @param courseId 所属课程ID
     * @param request 章节创建请求参数
     * @param teacherId 创建章节的教师ID
     * @return 创建后的章节详情响应
     * @throws BusinessException 当课程不存在或教师没有权限时抛出
     */
    public LessonResponse createLesson(Long courseId, LessonRequest request, Long teacherId) {
        Course course = courseRepository.findById(courseId)
                .orElseThrow(() -> new BusinessException(ErrorCode.COURSE_NOT_FOUND));
        
        if (!course.getTeacherId().equals(teacherId)) {
            throw new BusinessException(ErrorCode.PERMISSION_DENIED);
        }
        
        Integer orderNo = request.getOrderNo() != null ? request.getOrderNo() : lessonRepository.getNextOrderNo(courseId);
        Lesson lesson = new Lesson(courseId, request.getTitle(), orderNo);
        lesson.setLessonType(request.getLessonType());
        lesson.setIsFree(request.getIsFree());
        lesson.setContentUrl(request.getContentUrl());
        lesson.setVideoUrl(request.getVideoUrl());
        lesson.setDuration(request.getDuration());
        
        return new LessonResponse(lessonRepository.save(lesson));
    }
    
    /**
     * 更新课程章节信息
     * @param id 要更新的章节ID
     * @param request 章节更新请求参数
     * @param teacherId 当前操作的教师ID
     * @return 更新后的章节详情响应
     * @throws BusinessException 当章节不存在、所属课程不存在或教师没有权限时抛出
     */
    public LessonResponse updateLesson(Long id, LessonRequest request, Long teacherId) {
        Lesson lesson = lessonRepository.findById(id)
                .orElseThrow(() -> new BusinessException(ErrorCode.LESSON_NOT_FOUND));
        
        Course course = courseRepository.findById(lesson.getCourseId())
                .orElseThrow(() -> new BusinessException(ErrorCode.COURSE_NOT_FOUND));
        
        if (!course.getTeacherId().equals(teacherId)) {
            throw new BusinessException(ErrorCode.PERMISSION_DENIED);
        }
        
        lesson.setTitle(request.getTitle());
        lesson.setLessonType(request.getLessonType());
        lesson.setIsFree(request.getIsFree());
        lesson.setContentUrl(request.getContentUrl());
        lesson.setVideoUrl(request.getVideoUrl());
        lesson.setDuration(request.getDuration());
        if (request.getOrderNo() != null) {
            lesson.setOrderNo(request.getOrderNo());
        }
        
        return new LessonResponse(lessonRepository.save(lesson));
    }
    
    /**
     * 删除课程章节
     * @param id 要删除的章节ID
     * @param teacherId 当前操作的教师ID
     * @throws BusinessException 当章节不存在、所属课程不存在或教师没有权限时抛出
     */
    public void deleteLesson(Long id, Long teacherId) {
        Lesson lesson = lessonRepository.findById(id)
                .orElseThrow(() -> new BusinessException(ErrorCode.LESSON_NOT_FOUND));
        
        Course course = courseRepository.findById(lesson.getCourseId())
                .orElseThrow(() -> new BusinessException(ErrorCode.COURSE_NOT_FOUND));
        
        if (!course.getTeacherId().equals(teacherId)) {
            throw new BusinessException(ErrorCode.PERMISSION_DENIED);
        }
        
        lessonRepository.delete(lesson);
    }
}





